//
//  JRTXDiagramDataToCoordsConverter.m
//  
//
//  Created by JIRENTIANXIANG on 6/21/15.
//
//

#import "JRTXDiagramDataDisplayMapper.h"
#import "JRTXDiagramViewConfiguration.h"
#import "JRTXDiagramView.h"
#import "JRTXDiagramDatum.h"
#import "JRTXDiagramPoint.h"
#import <QuartzCore/QuartzCore.h>

@interface JRTXDiagramDataDisplayMapper()

@property (weak,nonatomic) JRTXDiagramView* diagramView;
@property (strong,nonatomic) NSArray* points;
@property (readonly,nonatomic) float xScale;
@property (readonly,nonatomic) float yScale;

@end

@implementation JRTXDiagramDataDisplayMapper

+(instancetype)mapperForDiagramView:(JRTXDiagramView *)diagramView
{
    id mapper=[[[self class] alloc] initWithDiagramView:diagramView];
    return mapper;
}

-(instancetype)initWithDiagramView:(JRTXDiagramView*)diagramView
{
    if (self=[super init]) {
        self.diagramView=diagramView;
        self.points=[[NSArray alloc] init];
    }
    return self;
}

-(void)update
{
    NSMutableArray* xData=[NSMutableArray array];
    NSMutableArray* yData=[NSMutableArray array];
    for (JRTXDiagramDatum* datum in self.diagramView.diagramData) {
        [xData addObject:datum.x];
        [yData addObject:datum.y];
    }
    _maxX=[JRTXDiagramDataDisplayMapper maxNumberInNumbers:xData];
    _minX=[JRTXDiagramDataDisplayMapper minNumberInNumbers:xData];
    _maxY=[JRTXDiagramDataDisplayMapper maxNumberInNumbers:yData];
    _minY=[JRTXDiagramDataDisplayMapper minNumberInNumbers:yData];
    _xSpan=self.maxX-self.minX;
    _ySpan=self.maxY-self.minY;
    CGRect graphArea=self.diagramView.graphArea;
    _xScale=graphArea.size.width/_xSpan;
    _yScale=graphArea.size.height/_ySpan;
    NSMutableArray* points=[NSMutableArray array];
    for (JRTXDiagramDatum* datum in self.diagramView.diagramData) {
        JRTXDiagramPoint* point=[self pointFromDatum:datum];
        if ((!isnan(point.point.x))&&(!isnan(point.point.y))) {
            [points addObject:point];
        }
    }
    self.points=points;
}

-(JRTXDiagramPoint*)pointFromDatum:(JRTXDiagramDatum *)datum
{
    CGFloat xCoord=[self xCoordFromValue:datum.x];
    CGFloat yCoord=[self yCoordFromValue:datum.y];
    return [JRTXDiagramPoint pointWithX:xCoord andY:yCoord];
}

-(CGFloat)xCoordFromValue:(NSNumber *)value
{
    CGRect graphArea=self.diagramView.graphArea;
    CGFloat xCoord=graphArea.origin.x+(value.floatValue-self.minX)*self.xScale;
    return xCoord;
}

-(CGFloat)yCoordFromValue:(NSNumber *)value
{
    CGRect graphArea=self.diagramView.graphArea;
    CGPoint origin=graphArea.origin;
    CGSize size=graphArea.size;
    CGFloat yCoord=origin.y+size.height-(value.floatValue-self.minY)*self.yScale;
    CGFloat avrY=origin.y+size.height/2;
    return self.diagramView.configuration.verticalScale*(yCoord-avrY)+avrY;
}

//------------------------------------------------------------------
// private
//------------------------------------------------------------------
+(float)maxNumberInNumbers:(NSArray*)numbers
{
    float max=((NSNumber*)numbers.firstObject).floatValue;
    for (NSNumber* number in numbers) {
        double value=number.floatValue;
        if (value>max) {
            max=value;
        }
    }
    return max;
}
+(float)minNumberInNumbers:(NSArray*)numbers
{
    double min=((NSNumber*)numbers.firstObject).floatValue;
    for (NSNumber* number in numbers) {
        double value=number.floatValue;
        if (value<min) {
            min=value;
        }
    }
    return min;
}
//------------------------------------------------------------------

@end
